package com.xunji.user.controller;


import com.xunji.user.common.R;
import com.xunji.user.dto.MenuDto;
import com.xunji.user.entity.Menu;
import com.xunji.user.entity.RoleMenu;
import com.xunji.user.entity.UserRole;
import com.xunji.user.service.MenuService;
import com.xunji.user.service.RoleMenuService;
import com.xunji.user.service.UserRoleService;
import com.xunji.user.util.RequestContextUtil;
import com.xunji.user.vo.rep.UserMenuQueryResponse;
import com.xunji.user.vo.req.MenuAddRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/menu")
@Api(tags = "菜单管理")
public class MenuController {


    @Resource
    MenuService menuService;
    @Resource
    UserRoleService userRoleService;

    @Resource
    RoleMenuService roleMenuService;

    @GetMapping("")
    @ApiOperation(value = "查询所有菜单", notes = "查询所有菜单")
    public R getMenus() {
        return R.success(menuService.getMenus());
    }

    @GetMapping("/current_user")
    @ApiOperation(value = "查询当前登录用户菜单", notes = "查询当前登录用户菜单")
    public R getMenusByUserId(HttpServletRequest  request) {
        String userId = RequestContextUtil.getUser(request);
        UserMenuQueryResponse response = new UserMenuQueryResponse();
        List<UserRole> roles = userRoleService.selectByUserId(userId);
        //根据角色查询菜单
        if (!CollectionUtils.isEmpty(roles)) {
            List<String> roleIds = roles.stream().map(UserRole::getRoleId).collect(Collectors.toList());
            List<RoleMenu> menus = roleMenuService.getByRoleIds(roleIds);
            if (!CollectionUtils.isEmpty(menus)) {
                Set<Integer> menuIds = menus.stream().map(RoleMenu::getMenuId).collect(Collectors.toSet());
                List<Menu> menuList = menuService.getMenusByIds(new ArrayList<>(menuIds));
                List<MenuDto> menuDtos = menuList.stream().map(MenuDto::getInstance).collect(Collectors.toList());
                response.setMenus(makePidTree(menuDtos, 0));
            }
        }
        return R.success(response);
    }

    private List<MenuDto> makePidTree(List<MenuDto> orgQueryResponses, Integer pid) {
        List<MenuDto> children = orgQueryResponses.stream().filter(x -> x.getPId().equals(pid)).sorted(Comparator.comparing(MenuDto::getWeight)).collect(Collectors.toList());
        List<MenuDto> successor = orgQueryResponses.stream().filter(x -> !x.getPId().equals(pid)).collect(Collectors.toList());
        children.forEach(x -> {
            x.setChildren(makePidTree(successor, x.getId()));
        });
        return children;
    }

    @PutMapping("")
    @ApiOperation(value = "新增菜单", notes = "新增菜单")
    public R addMenu(@RequestBody MenuAddRequest request) {
        try {
            // 增加重名校验
            String name = request.getName();
            if (!StringUtils.hasText(name)) return R.failure("资源名称不能为空！");
            List<Menu> menus = menuService.selectByName(name);
            if (menus != null && !menus.isEmpty()) return R.failure("资源名称重复！");
            menuService.addMenu(request);
            return R.success();
        } catch (Exception e) {
            log.error("新增菜单失败，e->{}", e);
            return R.failure("新增菜单失败");
        }
    }

    @DeleteMapping("/{id}")
    @ApiOperation(value = "删除菜单", notes = "删除菜单")
    public R deleteMenu(@PathVariable("id") Integer id) {
        try {
            menuService.deleteById(id);
            return R.success();
        } catch (Exception e) {
            log.error("删除菜单失败，e->{}", e);
            return R.failure("删除菜单失败");
        }
    }

}
